import fs from 'fs/promises';
import path from 'path';
import { Province, City, District, LocationData, LocationQuery, OilPriceByLocationRequest, OilPriceByLocationResponse } from '@/types/location';
import { OilPriceService } from './oilPriceService';

// 本地数据文件路径
const LOCAL_DATA_DIR = path.join(__dirname, '..', 'province-city-china');
const PROVINCE_FILE = path.join(LOCAL_DATA_DIR, 'province.json');
const CITY_FILE = path.join(LOCAL_DATA_DIR, 'city.json');
const AREA_FILE = path.join(LOCAL_DATA_DIR, 'area.json');

export class LocationService {
  private static instance: LocationService;
  private locationData: LocationData | null = null;
  private cache = new Map<string, any>();
  private cacheExpiry = new Map<string, number>();
  private readonly CACHE_TTL = 24 * 60 * 60 * 1000; // 24小时缓存

  private constructor() {}

  public static getInstance(): LocationService {
    if (!LocationService.instance) {
      LocationService.instance = new LocationService();
    }
    return LocationService.instance;
  }

  /**
   * 初始化地理位置数据
   */
  async initialize(): Promise<void> {
    try {
      console.log('开始初始化地理位置数据...');
      
      // 尝试从本地文件加载
      if (await this.loadFromLocalFile()) {
        console.log('从本地文件加载地理位置数据成功');
        return;
      }

      // 如果本地文件不存在，使用内置的默认数据
      console.log('本地文件不存在，使用内置默认数据');
      this.locationData = this.getBuiltInData();
      
      console.log('地理位置数据初始化完成');
    } catch (error) {
      console.error('初始化地理位置数据失败:', error);
      // 使用内置数据作为后备
      this.locationData = this.getBuiltInData();
    }
  }

  /**
   * 从本地文件加载数据
   */
  private async loadFromLocalFile(): Promise<boolean> {
    try {
      // 检查文件是否存在
      await fs.access(PROVINCE_FILE);
      await fs.access(CITY_FILE);
      await fs.access(AREA_FILE);

      // 读取省份数据
      const provinceData = JSON.parse(await fs.readFile(PROVINCE_FILE, 'utf-8'));
      
      // 读取城市数据
      const cityData = JSON.parse(await fs.readFile(CITY_FILE, 'utf-8'));
      
      // 读取区域数据
      const areaData = JSON.parse(await fs.readFile(AREA_FILE, 'utf-8'));

      // 构建数据结构
      this.locationData = this.buildLocationData(provinceData, cityData, areaData);
      
      return true;
    } catch (error) {
      console.warn('无法从本地文件加载数据:', error);
      return false;
    }
  }

  /**
   * 构建地理位置数据结构
   */
  private buildLocationData(provinceData: any[], cityData: any[], areaData: any[]): LocationData {
    const provinces: Province[] = [];

    // 处理省份数据
    for (const province of provinceData) {
      const provinceObj: Province = {
        code: province.code,
        name: province.name,
        shortName: this.getShortName(province.name),
        cities: []
      };

      // 查找该省份下的城市
      const cities = cityData.filter(city => city.province === province.province);
      for (const city of cities) {
        const cityObj: City = {
          code: city.code,
          name: city.name,
          shortName: this.getShortName(city.name),
          districts: []
        };

        // 查找该城市下的区域
        const districts = areaData.filter(area => 
          area.province === city.province && area.city === city.city
        );
        
        for (const district of districts) {
          const districtObj: District = {
            code: district.code,
            name: district.name,
            shortName: this.getShortName(district.name)
          };
          cityObj.districts.push(districtObj);
        }

        provinceObj.cities.push(cityObj);
      }

      provinces.push(provinceObj);
    }

    return { provinces };
  }

  /**
   * 获取简称
   */
  private getShortName(fullName: string): string {
    // 移除常见的行政区划后缀
    return fullName
      .replace(/省$/, '')
      .replace(/市$/, '')
      .replace(/区$/, '')
      .replace(/县$/, '')
      .replace(/自治州$/, '')
      .replace(/特别行政区$/, '')
      .replace(/自治区$/, '');
  }

  /**
   * 获取内置的默认数据（作为后备）
   */
  private getBuiltInData(): LocationData {
    return {
      provinces: [
        {
          code: '110000',
          name: '北京市',
          shortName: '北京',
          cities: [
            {
              code: '110100',
              name: '北京市',
              shortName: '北京',
              districts: [
                { code: '110101', name: '东城区', shortName: '东城' },
                { code: '110102', name: '西城区', shortName: '西城' },
                { code: '110105', name: '朝阳区', shortName: '朝阳' },
                { code: '110106', name: '丰台区', shortName: '丰台' },
                { code: '110107', name: '石景山区', shortName: '石景山' },
                { code: '110108', name: '海淀区', shortName: '海淀' }
              ]
            }
          ]
        },
        {
          code: '310000',
          name: '上海市',
          shortName: '上海',
          cities: [
            {
              code: '310100',
              name: '上海市',
              shortName: '上海',
              districts: [
                { code: '310101', name: '黄浦区', shortName: '黄浦' },
                { code: '310104', name: '徐汇区', shortName: '徐汇' },
                { code: '310105', name: '长宁区', shortName: '长宁' },
                { code: '310106', name: '静安区', shortName: '静安' },
                { code: '310107', name: '普陀区', shortName: '普陀' }
              ]
            }
          ]
        }
      ]
    };
  }

  /**
   * 搜索地理位置
   */
  searchLocations(query: LocationQuery): Province[] {
    if (!this.locationData) {
      return [];
    }

    const { keyword, province, city, district } = query;
    let results = this.locationData.provinces;

    // 按省份筛选
    if (province) {
      results = results.filter(p => 
        p.name.includes(province) || p.shortName?.includes(province)
      );
    }

    // 按城市筛选
    if (city) {
      results = results.map(p => ({
        ...p,
        cities: p.cities.filter(c => 
          c.name.includes(city) || c.shortName?.includes(city)
        )
      })).filter(p => p.cities.length > 0);
    }

    // 按区域筛选
    if (district) {
      results = results.map(p => ({
        ...p,
        cities: p.cities.map(c => ({
          ...c,
          districts: c.districts.filter(d => 
            d.name.includes(district) || d.shortName?.includes(district)
          )
        })).filter(c => c.districts.length > 0)
      })).filter(p => p.cities.length > 0);
    }

    // 按关键词搜索
    if (keyword) {
      results = results.map(p => ({
        ...p,
        cities: p.cities.map(c => ({
          ...c,
          districts: c.districts.filter(d => 
            d.name.includes(keyword) || d.shortName?.includes(keyword) ||
            c.name.includes(keyword) || c.shortName?.includes(keyword) ||
            p.name.includes(keyword) || p.shortName?.includes(keyword)
          )
        })).filter(c => c.districts.length > 0)
      })).filter(p => p.cities.length > 0);
    }

    return results;
  }

  /**
   * 根据地理位置查询油价
   */
  async getOilPriceByLocation(request: OilPriceByLocationRequest): Promise<OilPriceByLocationResponse> {
    try {
      const oilPriceService = OilPriceService.getInstance();
      const { province, city, district, fuelType = '92', includeNearby = false } = request;

      // 获取该地区的油价数据
      const oilPrices = await oilPriceService.getOilPrices(province, true);

      if (oilPrices.length === 0) {
        return {
          success: false,
          message: '未找到该地区的油价数据',
          data: null
        };
      }

      const oilPrice = oilPrices[0]; // 获取最新数据
      if (!oilPrice) {
        return {
          success: false,
          message: '油价数据无效',
          data: null
        };
      }

      let price: number;

      // 根据燃油类型获取价格
      switch (fuelType) {
        case '92':
          price = oilPrice.price92;
          break;
        case '95':
          price = oilPrice.price95;
          break;
        case '98':
          price = oilPrice.price98;
          break;
        case '0':
          price = oilPrice.price0;
          break;
        default:
          price = oilPrice.price92;
      }

      // 如果需要包含附近地区的数据
      let nearbyPrices: Array<{
        province: string;
        price92: number;
        price95: number;
        price98: number;
        price0: number;
        updateTime: Date;
      }> | undefined = undefined;

      if (includeNearby) {
        const allPrices = await oilPriceService.getOilPrices(undefined, true);
        nearbyPrices = allPrices.slice(0, 5).map(p => ({
          province: p.province,
          price92: p.price92,
          price95: p.price95,
          price98: p.price98,
          price0: p.price0,
          updateTime: p.updateTime
        }));
      }

      const responseData: any = {
        location: {
          province,
          city: city || '',
          district: district || ''
        },
        fuelType,
        price,
        updateTime: oilPrice.updateTime
      };

      if (nearbyPrices) {
        responseData.nearbyPrices = nearbyPrices;
      }

      return {
        success: true,
        message: '查询成功',
        data: responseData
      };
    } catch (error) {
      console.error('根据地理位置查询油价失败:', error);
      return {
        success: false,
        message: '查询失败',
        data: null,
        error: error instanceof Error ? error.message : '未知错误'
      };
    }
  }

  /**
   * 获取所有省份
   */
  getAllProvinces(): Province[] {
    return this.locationData?.provinces || [];
  }

  /**
   * 根据省份代码获取城市列表
   */
  getCitiesByProvince(provinceCode: string): City[] {
    const province = this.locationData?.provinces.find(p => p.code === provinceCode);
    return province?.cities || [];
  }

  /**
   * 根据城市代码获取区域列表
   */
  getDistrictsByCity(cityCode: string): District[] {
    for (const province of this.locationData?.provinces || []) {
      for (const city of province.cities) {
        if (city.code === cityCode) {
          return city.districts;
        }
      }
    }
    return [];
  }

  /**
   * 获取缓存
   */
  getCache(key: string): any {
    const expiry = this.cacheExpiry.get(key);
    if (expiry && Date.now() < expiry) {
      return this.cache.get(key);
    }
    return null;
  }

  /**
   * 设置缓存
   */
  setCache(key: string, value: any, ttl: number = this.CACHE_TTL): void {
    this.cache.set(key, value);
    this.cacheExpiry.set(key, Date.now() + ttl);
  }

  /**
   * 清除缓存
   */
  clearCache(): void {
    this.cache.clear();
    this.cacheExpiry.clear();
  }

  /**
   * 获取缓存统计信息
   */
  getCacheStats(): { size: number; keys: string[] } {
    return {
      size: this.cache.size,
      keys: Array.from(this.cache.keys())
    };
  }
}
